#include <QDebug>
#include <QNetworkAccessManager>
#include <QNetworkReply>
#include <QMessageBox>
#include "loginwindow.h"
#include "ui_loginwindow.h"
#include "configfile.h"
#include "downclient.h"

LoginWindow::LoginWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::LoginWindow)
{
    ui->setupUi(this);
    if(parent) { qDebug() << "parent is not nullptr"; } else { qDebug() << "parent is nullptr"; }
    this->init();
}

LoginWindow::~LoginWindow()
{
    delete ui;
    this->deinit();
}

void LoginWindow::resetSignalAndSlot()
{
    disconnect(this->netManager,
               &QNetworkAccessManager::finished,
               this,
               &LoginWindow::requestHomepageFinished);
    connect(this->netManager,
            &QNetworkAccessManager::finished,
            this,
            &LoginWindow::requestFinished);
}

LoginWindow::Status LoginWindow::init()
{
    qDebug() << "LoginWindow::" << __FUNCTION__;

    /* init ui */
    this->settings = new ConfigFile(QCoreApplication::applicationDirPath() + "/" + DEFAULT_FILENAME);
    this->loginUrl = this->settings->value(USER_WEB_URL).toString();
    this->ui->lineEditUser->setText(this->settings->value(USER_NAME).toString());
    this->ui->lineEditPassword->setText(this->settings->value(USER_PASSWORD).toString());
    this->ui->checkBoxIsRmberPassword->setChecked(this->settings->value(USER_SAVE_PASSWORD).toBool());
    this->ui->checkBoxIsAutoLogin->setChecked(this->settings->value(USER_AUTO_LOGIN).toBool());

    /* init network */
    this->netManager = new QNetworkAccessManager(this);
    connect(this->netManager, &QNetworkAccessManager::finished, this, &LoginWindow::requestFinished);  //建立请求完成的槽

    return LoginWindow::NO_ERROR;
}

LoginWindow::Status LoginWindow::deinit()
{
    qDebug() << "LoginWindow::" << __FUNCTION__;
    this->settings->setValue(USER_PHPSESSID, ""); // 清空会话ID
    delete settings;
    delete netManager;
    return LoginWindow::NO_ERROR;
}

void LoginWindow::on_pushButtonLogin_clicked()
{
    qDebug() << "LoginWindow::" << __FUNCTION__;

    /* 构建请求URL */
    /* http://filegeli.timechicken.cc/index.php?user/loginSubmit&name=lingguangji&password=191 */
    QString loginUrl;
    loginUrl += this->settings->value(USER_WEB_URL).toString();
    loginUrl += QString("/index.php?user/loginSubmit&name=%1&password=%2")
            .arg(this->ui->lineEditUser->text())
            .arg(this->ui->lineEditPassword->text());
    qDebug() << "LoginWindow::" << __FUNCTION__ << "URL:" << loginUrl;
    QNetworkRequest request = QNetworkRequest(QUrl(loginUrl));
    netManager->get(request);

    /* 清空上一次保留的session ID */
    this->settings->setValue(USER_PHPSESSID, "");
}

/*
 * 登录请求发送后响应的数据
 */
void LoginWindow::requestFinished(QNetworkReply* reply)
{
    qDebug() << "LoginWindow::" << __FUNCTION__;
    /* 过滤请求错误 */
    if(reply->error() != QNetworkReply::NoError) {
        QMessageBox::critical(this, "Login Error", reply->errorString());
        return;
    }

    /* 判断响应数据 */
    QVariant statusCode = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute);
    /* 如果解析响应状态码错误或者状态码!=200 */
    /* 因为服务器会软重定向url为其他地址，所以要判断302状态码 */
    /* 如果返回200状态码就意味着账号或着密码错误了 */
    qDebug() << "requestFinished Response statusCode:" << statusCode.toInt();
    if(!statusCode.isValid() || statusCode.toInt() != 302) {
        if(statusCode.toInt() == 200) {
            QMessageBox::critical(this, "Response Error", "用户名不存在或密码不正确，请检查后重试。");
            return ;
        }
        QVariant reason =  reply->attribute(QNetworkRequest::HttpReasonPhraseAttribute);
        if(reason.isValid())
            QMessageBox::critical(this, "Response Error", reason.toString());
        else
            QMessageBox::critical(this, "Response Error", "响应错误");
        return ;
    }

    /* 解析数据，截取会话PHPSESSID */
//    qDebug() << "ResponseData: \n" << QString(reply->readAll());
    if(reply->hasRawHeader(QByteArray("Set-Cookie"))) {
        QString setCookie = QString(reply->rawHeader(QByteArray("Set-Cookie")));
        qDebug() << "Set-Cookie:" << setCookie;
        int phpSessIdIndex = setCookie.indexOf("PHPSESSID=");
        if(phpSessIdIndex == -1) {
            QMessageBox::critical(this, "Response Error", "Not find \"PHPSESSID\" in the Cookie.");
            return ;
        }
        phpSessIdIndex += QString("PHPSESSID=").length();
        this->phpSessionID = setCookie.mid(phpSessIdIndex,
                                           setCookie.indexOf(';', phpSessIdIndex) - phpSessIdIndex);
        qDebug() << "PHPSESSID=" << this->phpSessionID;
        this->settings->setValue(QString(USER_PHPSESSID), this->phpSessionID);
    } else {
        QList<QByteArray> replyHeaderList = reply->rawHeaderList();
        qDebug() << "LoginWindow::" << __FUNCTION__ << "ReplyHeaderList:";
        foreach(QByteArray i, replyHeaderList) {
            qDebug() << i << QString(reply->rawHeader(i));
        }
        QMessageBox::critical(this, "Response Error", "Not find \"Set-Cookie\" in the Headers.");
    }
    qDebug() << "LoginWindow::" << __FUNCTION__ << ": Login Succeed.";

    /* init request homepage network env */
    disconnect(this->netManager,
               &QNetworkAccessManager::finished,
               this,
               &LoginWindow::requestFinished);
    connect(this->netManager,
            &QNetworkAccessManager::finished,
            this,
            &LoginWindow::requestHomepageFinished);

    /* 构建请求主页的URL */
    QString homepageUrl;
    homepageUrl += this->settings->value(USER_WEB_URL).toString() + "/index.php";
    QNetworkRequest requestHomepage = QNetworkRequest(QUrl(homepageUrl));
    /* PHPSESSID=110c5e84164fab90ab07b5be30ea1cd0; secros_user_language=zh_CN; secros_name=lingguangji */
    requestHomepage.setRawHeader(QByteArray("Cookie"),
                                 QString("PHPSESSID=%1; secros_user_language=zh_CN; secros_name=%2")
                                 .arg(this->phpSessionID)
                                 .arg(this->settings->value(USER_NAME).toString())
                                 .toUtf8());
    requestHomepage.setRawHeader(QByteArray("Host"),
                                 this->settings->value(USER_WEB_URL).toString().mid(7).toUtf8());
    requestHomepage.setRawHeader(QByteArray("Referer"),
                                 QString(this->settings->value(USER_WEB_URL).toString() + "/index.php?user/login")
                                 .toUtf8());
    requestHomepage.setHeader(QNetworkRequest::UserAgentHeader,
                              "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/104.0.0.0 Safari/537.36"
                              );
    requestHomepage.setRawHeader(QByteArray("Accept"),
                                 "*/*");
    this->netManager->get(requestHomepage);
}

void LoginWindow::requestHomepageFinished(QNetworkReply *reply)
{
    qDebug() << "LoginWindow::" << __FUNCTION__;
    /* 过滤请求错误 */
    if(reply->error() != QNetworkReply::NoError) {
        QMessageBox::critical(this, "Login Error", reply->errorString());
        return;
    }

    /* 判断响应数据 */
    QVariant statusCode = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute);
    /* 如果解析响应状态码错误或者状态码!=200 */
    qDebug() << "requestHomepageFinished Response statusCode:" << statusCode.toInt();
    if(!statusCode.isValid() || statusCode.toInt() != 200) {
        QVariant reason =  reply->attribute(QNetworkRequest::HttpReasonPhraseAttribute);
        if(reason.isValid())
            QMessageBox::critical(this, "Response Error", reason.toString());
        else
            QMessageBox::critical(this, "Response Error", "响应错误");
        return ;
    }

    /* 响应成功，开始解析数据 */
//    QList<QByteArray> replyHeadersList = reply->rawHeaderList();
//    foreach(QByteArray i, replyHeadersList) {
//        qDebug() << i << reply->rawHeader(i);
//    }
//    qDebug() << "ResponseData: \n" << QString(reply->readAll());

    /* 登录成功后记录登录状态 */
    if(this->ui->checkBoxIsRmberPassword->isChecked()) {
        this->settings->setValue(USER_PASSWORD, this->ui->lineEditPassword->text());
        this->settings->setValue(USER_SAVE_PASSWORD, "true");

    } else {
        this->settings->setValue(USER_PASSWORD, "");
        this->settings->setValue(USER_SAVE_PASSWORD, "false");
    }
    this->settings->setValue(USER_NAME, this->ui->lineEditUser->text());
    this->settings->setValue(USER_AUTO_LOGIN, this->ui->checkBoxIsAutoLogin->isChecked());

    /* hide windows */
    qDebug() << "LoginWindow::" << __FUNCTION__ << "LoginWindow hide.";
    DownClient *parentWindow = (DownClient *)this->parentWidget();
    if(parentWindow == nullptr) { qDebug() << "LoginWindow::init get parent is nullptr";  return ; }
    parentWindow->reloadConfig();
    parentWindow->setCentralWidget(parentWindow->getSourceCentralWidget());
    parentWindow->setGeometry(parentWindow->getSourceWindowRect());
    parentWindow->heartbeatStart();
}

/***************************************************
 * @brief 勾选自动登录之后必须记住密码，否则无法登录
 */
void LoginWindow::on_checkBoxIsAutoLogin_stateChanged(int staus)
{
    this->ui->checkBoxIsRmberPassword->setChecked(true);
    this->ui->checkBoxIsRmberPassword->setDisabled(staus?true:false);
}

/***************************************************
 * @brief 按下 回显密码按钮的事件
 */
void LoginWindow::on_pushButtonEchoPassword_pressed()
{
    ui->lineEditPassword->setEchoMode(QLineEdit::Normal);
    ui->pushButtonEchoPassword->setStyleSheet("border-image: url(:/eyesee.png);");
}

/***************************************************
 * @brief 松开 回显密码按钮的事件
 */
void LoginWindow::on_pushButtonEchoPassword_released()
{
    ui->lineEditPassword->setEchoMode(QLineEdit::Password);
    ui->pushButtonEchoPassword->setStyleSheet("border-image: url(:/eyenone.png);");
}

void LoginWindow::keyReleaseEvent(QKeyEvent *ev)
{
    qDebug() << "LoginWindow::" << __FUNCTION__ << "Key:" << ev->key();
    switch (ev->key()) {
    case Qt::Key_Enter:
    case Qt::Key_Return:
        this->on_pushButtonLogin_clicked();
        break;
    }
}
